package com.ray.tool.json;

import com.google.gson.*;

import java.lang.reflect.Type;

/**
 * Ray框架 Json 工具类
 * 依赖于阿里的JSON包
 *
 * @author LiaoYuXing-Ray
 * @version 1.0
 * @createDate 2023/10/7 15:01
 **/
@SuppressWarnings("unused")
public class RayJsonTools {
    /**
     * 工具类中的方法都是静态方法访问的，因此将构造器私有不允许创建对象
     * 2023/10/7 15:01
     */
    private RayJsonTools() {
        throw new AssertionError();
    }

    /**
     * 判断传入字符串格式是否为Json格式字符串
     *
     * @param jsonStr 需要判断的字符串类型
     * @return boolean true为是
     * @author LiaoYuXing 2023/8/4 15:32
     **/
    public static boolean verifyStrIsJson(String jsonStr) {
        boolean result = false;
        Gson gson = new Gson();
        try {
            gson.fromJson(jsonStr, Object.class);
            result = true;
        } catch (Exception ex) {
            // 传入字符串不是JSON格式
        }
        return result;
    }

    /**
     * [Java对象]转[JSON字符串]
     *
     * @param obj Java对象
     * @return java.lang.String
     * @author LiaoYuXing-Ray 2023/10/7 15:46
     **/
    public static String javaObjectToJsonStr(Object obj) {
        Gson gson = new Gson();
        return gson.toJson(obj);
    }

    /**
     * [Java对象]转[JSON字符串] - 重载
     * 格式化输出JSON字符串/JSON字符串格式化输出
     *
     * @param obj  Java对象
     * @param flag 是否需要格式化
     * @return java.lang.String
     * @author LiaoYuXing-Ray 2023/10/7 15:46
     **/
    public static String javaObjectToJsonStr(Object obj, boolean flag) {
        if (flag) {
            Gson gson = new GsonBuilder().serializeNulls().setPrettyPrinting().create();
            return gson.toJson(obj);
        }
        return javaObjectToJsonStr(obj);
    }

    /**
     * [Java对象]转[JSON对象]
     *
     * @param obj Java对象
     * @return com.alibaba.fastjson.JSONObject
     * @author LiaoYuXing-Ray 2023/10/7 15:46
     **/
    public static JsonObject javaObjectToJsonObject(Object obj) {
        Gson gson = new Gson();
        return gson.toJsonTree(obj).getAsJsonObject();
    }

    /**
     * [JSON对象]转[Java对象]
     *
     * @param jsonObject JSON对象
     * @param clazz      Java对象
     * @return Java对象
     * @author LiaoYuXing-Ray 2023/10/7 15:46
     **/
    public static <T> T jsonStrToJavaObject(JsonObject jsonObject, Class<T> clazz) {
        Gson gson = new Gson();
        return gson.fromJson(jsonObject, clazz);
    }


    /**
     * [JSON字符串]转[Java对象]
     *
     * @param jsonStr JSON字符串
     * @param clazz   Java对象
     * @return Java对象
     * @author LiaoYuXing-Ray 2023/10/7 15:46
     **/
    public static <T> T jsonStrToJavaObject(String jsonStr, Class<T> clazz) {
        Gson gson = new Gson();
        return gson.fromJson(jsonStr, clazz);
    }


    /**
     * [JSON字符串]转[JSON对象]
     *
     * @param jsonStr JSON字符串
     * @return JSON对象
     * @author LiaoYuXing-Ray 2023/10/7 15:46
     **/
    public static JsonObject jsonStrToJsonObject(String jsonStr) {
        return jsonStrToJavaObject(jsonStr,JsonObject.class);
    }

    // 实现序列化和反序列化
    static class ClassCodec implements JsonSerializer<Class<?>>, JsonDeserializer<Class<?>> {

        @Override
        public Class<?> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
            try {
                String str = json.getAsString();
                return Class.forName(str);
            } catch (ClassNotFoundException e) {
                throw new JsonParseException(e);
            }
        }

        @Override
        public JsonElement serialize(Class<?> src, Type typeOfT, JsonSerializationContext context) {
            // class -> json
            return new JsonPrimitive(src.getName());
        }
    }
}
